#include <stdio.h>
#include <stdlib.h>

/*16位short类型转为二进制字符串*/
char* hexToBinStr(short hex) {
    char * arr = malloc(17);
    arr[16] = 0;
    unsigned short us = (unsigned short)hex;
    for(int i = 0; i < 16; i++) {
        char bit = ((us >> i) & 0x0001) == 0 ? '0' : '1';
        arr[15-i] = bit;
    }
    printf("%x -> %s\n", hex, arr);
    return arr;
}

/*计算unsigned类型的数开头有几个0*/
int head0Len(unsigned num) {
    unsigned us = 0x80000000;
    for(int i = 0; i < 32; i++) {
        if((us & num) == us) {
            return i;
        }
        us >>= 1;
    }
    return 32;
}

/*
 * CRC编码：输入为16位序列，查表可知多项式取6位的100101，输出为21位CRC编码。
 * 编码原理：
 * 1.16位序（a16）列右边补5个0，变为21位（a21）；
 * 2.a21对多项式（multi）取余，得到5位余数（remainder）；
 * 3.用remainder替换a21的低5位就得到了最终CRC编码输出（crc）。
 * */
int crc(unsigned a16 , unsigned multi) {
    printf("sizeof(long):%d\n", sizeof(long)); // 4
    printf("sizeof(int):%d\n", sizeof(int)); // 4
    int h = head0Len((unsigned short)a16);
    h = h + 16 - 5; // h表示a21高位有h个0
    unsigned a21 = a16 << 5; // 16位序列右边补5个0，扩展为21位


}

/*模2求余*/
unsigned mod2Remainder(unsigned serial, unsigned divider) {
    int intLen = sizeof(int) * 8;
    int h1 = head0Len(serial);
    int h2 = head0Len(divider);
    //printf("h1:%d, h2:%d\n", h1, h2);
    if(h1 > h2) { // 被除数小于除数，直接返回被除数
        return serial;
    }
    unsigned currDivider = divider << (h2 - h1);
    unsigned newSerial = serial ^ currDivider;
    return mod2Remainder(newSerial, divider);
}




int main() {
    printf("sizeof(short):%d\n", sizeof(short));
    hexToBinStr(0x7c2a);
    printf("head0Len(0x8081):%d\n", head0Len(0x8081)); // 0
    printf("head0Len(0x31):%d\n", head0Len(0x31)); // 10
    printf("head0Len(0x21f):%d\n", head0Len(0x21f)); // 6
    unsigned int a = 0x20;
    printf("%x\n", mod2Remainder(a, 0x25)); // a
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // 14
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    printf("%x\n", mod2Remainder(a*=2, 0x25)); // d
    return 0;
}
